package controllers;

import models.AppUser;
import models.Client;
import models.Collaborator;
import models.Notification;
import models.Profile;
import models.Skill;
import models.SkillCategory;
import models.SkillSubCategory;
import models.UserRole;
import play.Logger;
import play.data.validation.Required;
import play.mvc.Before;
import play.mvc.Controller;
import controllers.tools.Tools;

public class RTU extends Controller {

	private static AppUser _CONNECTED_USER;

	// /////////////////////////
	// / MODEL METHODS
	// /////////////////////////

	static void setConnectedUser() {

		if (Authentication.isConnected()
				&& Authentication.check(UserRole.RTU.name())) {
			AppUser user = AppUser
					.find("login = ?", Authentication.connected()).first();
			_CONNECTED_USER = user;

			Logger.debug("[RTU] %s (%s) is connected on askima !",
					user.getLogin(), user.getRole().name());
		} else {
			error("Unauthorized access !");
		}
	}

	static void loadModelElements() {

		renderArgs.put("user", _CONNECTED_USER);
		renderArgs.put("collaborators", Collaborator.findAll());
		renderArgs.put("tools", new Tools());
		renderArgs.put("clients", Client.findAll());
		renderArgs.put("skills", Skill.findAll());

		Logger.debug("[RTU] Model elements : updated.");
	}

	// /////////////////////////////
	// // RENDERING METHODS
	// /////////////////////////////

	/**
	 * Rendering method
	 */

	public static void area() {

		// Find the connected user
		setConnectedUser();
		// Load extra data before view rendering
		loadModelElements();

		// Logging
		Logger.debug("[RTU] Rendering RTU (%s) area...",
				_CONNECTED_USER.getLogin());

		// Rendering the RTU area
		render();
	}

	// ////////////////////////////
	// / NOTIFICATION METHODS
	// ////////////////////////////

	/**
	 * Send a notification to a collaborator
	 * 
	 * @param collaborator
	 * @param message
	 */

	public static void sendNotificationToCollaborator(String collaboratorID,
			String message) {

		if (collaboratorID == null || message == null || message.isEmpty()) {
			renderJSON(false);
			return;
		}
		Collaborator collaborator = Collaborator.findById(Integer
				.parseInt(collaboratorID));
		if (collaborator == null || collaborator.getUser() == null) {
			renderJSON(false);
			return;
		}
		Notification notif = new Notification(message, collaborator.getUser());
		notif.save();

		Logger.debug("[RTU] Notification sent for %s : %s", collaborator
				.getUser().getLogin(), message);
		renderJSON(true);
	}

	// /////////////////////////////
	// / CRUD METHODS
	// /////////////////////////////

	public static void addSkills(@Required String name,
			@Required SkillCategory category,
			@Required SkillSubCategory subcategory) {
		Skill newSkill = new Skill(name);
		newSkill.setCategory(category);
		newSkill.setSubcategory(subcategory);
		newSkill.save();
	}

	public static void updateSkill(@Required int skillId, String name,
			SkillCategory category, SkillSubCategory subcategory) {
		Skill modifSkill = Skill.findById(skillId);
		if (modifSkill == null) {
			error("Compétence inexistante");
			return;
		}
		modifSkill.setCategory(category);
		modifSkill.setName(name);
		modifSkill.setSubcategory(subcategory);
		modifSkill.merge();
		modifSkill.save();
	}

	public static void delSkill(@Required int skillId) {
		Skill delSkill = Skill.findById(skillId);
		delSkill.delete();
	}

	public static void addClient(@Required String name,
			@Required String address, @Required String country,
			@Required String zip, @Required String city,
			@Required String phone, @Required String email) {

		// Creates the new client object
		Client newClient = new Client();
		newClient.setName(name);
		newClient.setAddress(address);
		newClient.setZip(zip);
		newClient.setCity(city);
		newClient.setPhone(phone);
		newClient.setEmail(email);
		newClient.setCountry(country);
		newClient.save();

		// Logging
		Logger.debug("[RTU] Client : one more added (%s)", name);

		// Redirect the client on the RTU area
		area();
	}

	public static void updateClient(@Required int clientID,
			@Required String name, @Required String address,
			@Required String country, @Required String zip,
			@Required String city, @Required String phone,
			@Required String email) {

		// Search the client in the DB
		Client updateClient = Client.findById(clientID);

		if (updateClient == null) {
			// Logging
			Logger.debug("[RTU] Client not found : (id : %d)", clientID);
			error("Client inexistant !");
			return;
		}
		updateClient.setAddress(address);
		updateClient.setCity(city);
		updateClient.setEmail(email);
		updateClient.setName(name);
		updateClient.setPhone(phone);
		updateClient.setZip(zip);
		updateClient.setCountry(country);
		updateClient.merge();
		updateClient.save();

		// Logging
		Logger.debug("[RTU] Client : one updated (%d)", clientID);

		// Redirect the client on the RTU area
		area();
	}

	public static void delClient(@Required int clientId) {

		// Search client in the DB
		Client delClient = Client.findById(clientId);
		if (null == delClient) {
			renderJSON(false);
			return;
		}
		delClient.delete();

		// Logging
		Logger.debug("[RTU] Client : one deleted (%d)", clientId);

		// Returns true
		renderJSON(true);
	}

	public static void addCollab(@Required String name,
			@Required String firstname, @Required String login,
			@Required String pass) {

		// Creates a new user
		AppUser newUser = new AppUser();
		newUser.setLogin(login);
		newUser.setPass(pass);
		newUser.setRole(UserRole.COLLABORATOR);

		// Creates the associated collaborator
		models.Collaborator newCollab = new models.Collaborator();
		newCollab.setUser(newUser);
		Profile prof = new Profile();
		newCollab.setTmpProfile(prof);
		newCollab.getTmpProfil().setName(name);
		newCollab.getTmpProfil().setFirstname(firstname);
		Profile prof2 = new Profile();
		newCollab.setValidProfile(prof2);
		newCollab.getValidProfile().setName(name);
		newCollab.getValidProfile().setFirstname(firstname);
		prof.save();
		prof2.save();
		newUser.save();
		newCollab.save();

		// Logging
		Logger.debug("[RTU] Collaborator : one more created (%s)", name);

		// Redirect the client on the RTU area
		area();

	}

	public static void delCollab(@Required int collabId) {

		models.Collaborator delCollab = models.Collaborator.findById(collabId);
		if (null == delCollab) {
			renderJSON(false);
			return;
		}
		models.AppUser delAppUser = models.AppUser.findById(delCollab.getUser()
				.getUserID());
		if (null == delAppUser) {
			renderJSON(false);
			return;
		}
		models.Profile delTmpProfile = models.Profile.findById(delCollab
				.getTmpProfil().getProfileID());
		if (null == delTmpProfile) {
			renderJSON(false);
			return;
		}
		models.Profile delValidProfile = models.Profile.findById(delCollab
				.getValidProfile().getProfileID());
		if (null == delValidProfile) {
			renderJSON(false);
			return;
		}
		delTmpProfile.delete();
		delValidProfile.delete();
		delCollab.delete();
		delAppUser.delete();

		// Logging
		Logger.debug("[RTU] Collaborator : one deleted (%d)", collabId);

		// Returns true
		renderJSON(true);
	}

	// /////////////////////////////
	// // ASYNCHRONOUS METHODS
	// /////////////////////////////

	public static void clientToJSON(@Required int clientID) {

		Client client = Client.findById(clientID);
		if (null == client) {
			renderJSON(false);
			return;
		}
		renderJSON(client);
	}

}